<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>Benchmark: Element.setStyle()</title>
    <script type="text/javascript" src="prototype.js"></script>
    <script type="text/javascript" src="neodom.js"></script>
    <script type="text/javascript" src="benchmark.js"></script>
    <script type="text/javascript" src="benchmark_perlish.js"></script>
    <link rel="stylesheet" href="benchmark_style.css" type="text/css" />
  </head>
  <body class="test">
    <div id="body">
      <h1>
        <a href="benchmark.html">Benchmark</a>: <var>setStyle</var>
        <em>musing around <var>Prototype</var>'s <var>Element.setStyle()</var></em>
      </h1>
      <div id="content">
        <p>
          <a href="#" onclick="runTests(); return false;">Run tests</a>
          <input id="iterations" name="iterations" size="8" value="-1" /> times
          using this style:
          <input id="query" name="query" size="50"
            value="background-color: red; color: blue; font-size: 4em" />.
          <br />(<input type="checkbox" id="with-cleanup" checked="checked" />
            <label for="with-cleanup">cleanup after running each test</label>)
        </p>
        <p>
          <a href="#" onclick="$$('.tester').invoke('remove'); return false">clear results</a>
          ||
          <a href="#" onclick="$$('.testing').invoke('remove'); return false">remove test elements</a>
        </p>
      </div>
    </div>
    <script type="text/javascript">
/* <![CDATA[ */
if (typeof document.body.style.cssText != 'undefined') {
  function setCSSText(element, cssText, append) {
    if (append && !cssText) return element;
    if (append) {
      element.style.cssText += ';' + cssText;
    } else {
      element.style.cssText = cssText;
    }
    return element;
  };
} else {
  function setCSSText(element, cssText, append) {
    if (append && !cssText) return element;
    element.setAttribute('style', append
      ? element.getAttribute('style') + ';' + cssText
      : cssText
    )
    return element;
  };
}

String.prototype.parseStyleLite = function () {
  var ret = {};
  this.replace(/^\s*;+\s*/,'').replace(/\s*;+\s*$/,'').split(';').each(
    function (el) {
      var p = el.split(':');
      ret[ p[0].strip() ] = p[1].strip();
    }
  );
  return ret;
};

var UA     = navigator.userAgent,
    Gecko  = (UA.indexOf('Gecko') > -1),
    Safari = (UA.indexOf('Safari') > -1),
    Opera  = !!window.opera,
    IE     = (!Opera && UA.indexOf('MSIE') > -1),
    WebKit = /Konqueror|Safari|KHTML/.test(UA);

Element.addMethods({
  setStyleMv: function (element, style) {
    element = $(element);
    for (var name in style) {
      var value = style[name];
      if (name == 'opacity') {
        if (value == 1) {
          value = (Gecko && !WebKit) ? 0.999999 : 1.0;
          if (IE)
            element.style.filter = element.getStyle('filter').replace(/alpha\([^\)]*\)/gi,'');
        } else {
          if (value < 0.00001)
            value = 0;  
          if (IE)
            element.style.filter = element.getStyle('filter').replace(/alpha\([^\)]*\)/gi,'')
              + 'alpha(opacity='+value*100+')';
        }
      } else if (name == 'float') {
        name = (typeof element.style.styleFloat != 'undefined') ? 'styleFloat' : 'cssFloat';
      }
      element.style[name.camelize()] = value;
    }
    return element;
  },

  setStyleText: setCSSText
});

var styles, stylesText;
var methods = {
  setStyleText: function(){
    setCSSText(this.TEST, stylesText);
  },
  setStyleLite: function(){
    for (var name in styles)
      this.TEST.style[name.camelize()] = styles[name];
  },
  'E.setStyle': function(){
    this.TEST.setStyle(styles);
  },
  'E.setStyleMv': function(){
    this.TEST.setStyleMv(styles);
  },
  'E.setStyleText': function(){
    this.TEST.setStyleText(stylesText);
  }
};

function runTests() {
  stylesText = $F('query');
  styles = stylesText.parseStyleLite();
  new Benchmark(methods, {
    iterations: $F('iterations'),
    beforeTest: function() {
      var r = this.data[this.current];
      this.TEST = $T('p', document.body, {
            innerHTML: r.name + ': testing ' + r.iterations,
            className: 'testing'
          });
    },
    afterTest: $('with-cleanup').checked
      ? function() {this.TEST.remove()}
      : function(){}
  });
}
/* ]]> */
    </script>
  </body>
</html>
